package com.flyan.danmuhunter.common.utils;

import java.io.ByteArrayOutputStream;

/**
 * 字节数组工具类
 *
 * @author flyan
 * @version 1.0
 * @date 2022/6/7
 */
public class ByteArrayUtil {

    public static int readInt32(byte[] bytes, int pos) {
        int int32ByteLength = 4;
        if(pos + int32ByteLength > bytes.length) {
            return 0;
        }

        return byteLeftShift(bytes[pos], 24) |
                byteLeftShift(bytes[pos + 1], 16) |
                byteLeftShift(bytes[pos + 2], 8) |
                byteLeftShift(bytes[pos + 3], 0);
    }

    public static int readInt16(byte[] bytes, int pos) {
        int int16ByteLength = 2;
        if(pos + int16ByteLength > bytes.length) {
            return 0;
        }

        return byteLeftShift(bytes[pos], 8) |
                byteLeftShift(bytes[pos + 1], 0);
    }

    private static int byteLeftShift(byte b, int n) {
        return ((int)b) << n;
    }

    private static int byteRightShift(byte b, int n) {
        return ((int)b) >> n;
    }

    public static int writeInt32(byte[] bytes, int pos, int data) {
        int int32ByteLength = 4;
        for (int i = 0, shift = 24; i < int32ByteLength; i++, ++pos, shift -= 8) {
            bytes[pos] = (byte) ((data >>> shift) & 0xff);
        }

        return pos;
    }

    public static int writeInt16(byte[] bytes, int pos, int data) {
        int int32ByteLength = 2;
        for (int i = 0, shift = 8; i < int32ByteLength; i++, ++pos, shift -= 8) {
            bytes[pos] = (byte) ((data >>> shift) & 0xff);
        }

        return pos;
    }

    public static byte[] str2bytes(String str) {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        char[] chars = str.toCharArray();
        for (char c : chars) {
            if (c >= 0x000800) {
                bos.write(((c >> 12) & 0x0F) | 0xE0);
                bos.write(((c >> 6) & 0x3F) | 0x80);
                bos.write((c & 0x3F) | 0x80);
            } else if (c >= 0x000080) {
                bos.write(((c >> 6) & 0x1F) | 0xC0);
                bos.write((c & 0x3F) | 0x80);
            } else {
                bos.write(c & 0xFF);
            }
        }
        return bos.toByteArray();
    }

    public static byte[] slice(byte[] bytes, int off, int end) {
        if(off > end || off < 0 || off > bytes.length || end > bytes.length) {
            return null;
        }

        byte[] ans = new byte[end - off];
        System.arraycopy(bytes, off, ans, 0, end - off);
        return ans;
    }

}
